﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Jayden.Dll.Cards;
using Jayden.Dll.Cards.Poker;
using System.IO;
using Jayden.Dll.Cards.Poker.Enums;
using System.Xml;
using System.Threading;
using System.Globalization;
using System.Drawing.Imaging;
using Jayden.Dll.Cards.Drawing;

namespace Jayden.Windows.PokerClient
{
	public partial class PokerTableControl : UserControl
	{

		public class TableConfiguration
		{
			public string TableImage;
			public string BackgroundImage;
			public string ButtonImage;
			public string ChipsImage;
			public string CardImage;
			public string SeatImage;
			public string PodImage;
			public string PodActiveImage;
			public string TimerImage;

			public string FontFamily;
			public float FontSize;
			public Color FontColor;
			public Color SelectedColor;

			public Size CardSize = new Size(56, 78);
			public Size BackCardSize = new Size(42, 59);

			public Size Size;
			public Point PotPosition;
			public Point[] SeatPositions;
			public Point[] StackPositions;
			public Point[] ButtonPositions;
			public Point[] CardPositions;

			public void LoadConfiguration(string filename)
			{
				XmlDocument config = new XmlDocument();
				config.Load(filename);
				XmlElement tableView = config.DocumentElement;
				XmlElement images = tableView.SelectSingleNode("Images") as XmlElement;
				XmlAttribute buttonImg = images.Attributes["button"];
				XmlAttribute tableImg = images.Attributes["table"];
				XmlAttribute backgroundImg = images.Attributes["background"];
				XmlAttribute chipsImg = images.Attributes["chips"];
				XmlAttribute cardsImg = images.Attributes["card"];
				XmlAttribute seatImg = images.Attributes["seat"];
				XmlAttribute podOffImg = images.Attributes["pod"];
				XmlAttribute podOnImg = images.Attributes["podActive"];
				XmlAttribute timerImg = images.Attributes["timer"];
				XmlAttribute fontFamily = tableView.Attributes["font"];
				XmlAttribute fontSize = tableView.Attributes["fontSize"];
				XmlAttribute fontColor = tableView.Attributes["foreColor"];
				XmlAttribute selectedColor = tableView.Attributes["selectedColor"];
				XmlAttribute tableWidth = tableView.Attributes["width"];
				XmlAttribute tableHeight = tableView.Attributes["height"];
				XmlAttribute potX = tableView.Attributes["potX"];
				XmlAttribute potY = tableView.Attributes["potY"];
				XmlAttribute seats = tableView.Attributes["seats"];
				XmlAttribute cards = tableView.Attributes["cards"];

				Size = new System.Drawing.Size(int.Parse(tableWidth.Value), int.Parse(tableHeight.Value));
				PotPosition = new Point(int.Parse(potX.Value), int.Parse(potY.Value));
				SeatPositions = new Point[int.Parse(seats.Value)];
				StackPositions = new Point[SeatPositions.Length];
				ButtonPositions = new Point[SeatPositions.Length];
				CardPositions = new Point[int.Parse(cards.Value)];
				FontFamily = fontFamily.Value;
				FontColor = ColorTranslator.FromHtml(fontColor.Value);
				SelectedColor = ColorTranslator.FromHtml(selectedColor.Value);
				FontSize = float.Parse(fontSize.Value, CultureInfo.InvariantCulture);

				ButtonImage = buttonImg.Value;
				TableImage = tableImg.Value;
				BackgroundImage = backgroundImg.Value;
				ChipsImage = chipsImg.Value;
				CardImage = cardsImg.Value;
				SeatImage = seatImg.Value;
				PodActiveImage = podOnImg.Value;
				PodImage = podOffImg.Value;
				TimerImage = timerImg.Value;

				for (int c = 0; c < SeatPositions.Length; c++)
				{
					XmlElement seat = tableView.SelectSingleNode("Seat[@index=\"" + c + "\"]") as XmlElement;
					XmlAttribute seatX = seat.Attributes["x"];
					XmlAttribute seatY = seat.Attributes["y"];
					XmlAttribute stackX = seat.Attributes["stackX"];
					XmlAttribute stackY = seat.Attributes["stackY"];
					XmlAttribute buttonX = seat.Attributes["buttonX"];
					XmlAttribute buttonY = seat.Attributes["buttonY"];

					SeatPositions[c] = new Point(int.Parse(seatX.Value), int.Parse(seatY.Value));
					StackPositions[c] = new Point(int.Parse(stackX.Value), int.Parse(stackY.Value));
					ButtonPositions[c] = new Point(int.Parse(buttonX.Value), int.Parse(buttonY.Value));
				}
				for (int c = 0; c < CardPositions.Length; c++)
				{
					XmlElement card = tableView.SelectSingleNode("Card[@index=\"" + c + "\"]") as XmlElement;
					XmlAttribute cardX = card.Attributes["x"];
					XmlAttribute cardY = card.Attributes["y"];

					CardPositions[c] = new Point(int.Parse(cardX.Value), int.Parse(cardY.Value));
				}
			}
			public void SaveConfiguration(string filename)
			{
				XmlDocument config = new XmlDocument();
				XmlElement tableView = config.CreateElement("TableView");
				XmlElement images = config.CreateElement("Images");
				XmlAttribute buttonImg = config.CreateAttribute("button");
				XmlAttribute tableImg = config.CreateAttribute("table");
				XmlAttribute backgroundImg = config.CreateAttribute("background");
				XmlAttribute chipsImg = config.CreateAttribute("chips");
				XmlAttribute cardsImg = config.CreateAttribute("card");
				XmlAttribute seatImg = config.CreateAttribute("seat");
				XmlAttribute podOnImg = config.CreateAttribute("podActive");
				XmlAttribute podOffImg = config.CreateAttribute("pod");
				XmlAttribute timerImg = config.CreateAttribute("timer");
				XmlAttribute fontFamily = config.CreateAttribute("font");
				XmlAttribute fontSize = config.CreateAttribute("fontSize");
				XmlAttribute fontColor = config.CreateAttribute("foreColor");
				XmlAttribute selectedColor = config.CreateAttribute("selectedColor");
				XmlAttribute tableWidth = config.CreateAttribute("width");
				XmlAttribute tableHeight = config.CreateAttribute("height");
				XmlAttribute potX = config.CreateAttribute("potX");
				XmlAttribute potY = config.CreateAttribute("potY");
				XmlAttribute seats = config.CreateAttribute("seats");
				XmlAttribute cards = config.CreateAttribute("cards");
				config.AppendChild(tableView);
				tableView.Attributes.Append(tableWidth);
				tableView.Attributes.Append(tableHeight);
				tableView.Attributes.Append(potX);
				tableView.Attributes.Append(potY);
				tableView.Attributes.Append(seats);
				tableView.Attributes.Append(cards);
				tableView.Attributes.Append(fontFamily);
				tableView.Attributes.Append(fontSize); ;
				tableView.Attributes.Append(fontColor);
				tableView.Attributes.Append(selectedColor);
				tableView.AppendChild(images);
				images.Attributes.Append(tableImg);
				images.Attributes.Append(backgroundImg);
				images.Attributes.Append(buttonImg);
				images.Attributes.Append(chipsImg);
				images.Attributes.Append(cardsImg);
				images.Attributes.Append(seatImg);
				images.Attributes.Append(podOffImg);
				images.Attributes.Append(podOnImg);
				images.Attributes.Append(timerImg);

				tableWidth.Value = Size.Width.ToString();
				tableHeight.Value = Size.Height.ToString();
				potX.Value = PotPosition.X.ToString();
				potY.Value = PotPosition.Y.ToString();
				seats.Value = SeatPositions.Length.ToString();
				cards.Value = CardPositions.Length.ToString();
				fontFamily.Value = FontFamily;
				fontSize.Value = FontSize.ToString(CultureInfo.InvariantCulture);
				fontColor.Value = ColorTranslator.ToHtml(FontColor);
				selectedColor.Value = ColorTranslator.ToHtml(SelectedColor);

				tableImg.Value = TableImage;
				backgroundImg.Value = BackgroundImage;
				buttonImg.Value = ButtonImage;
				chipsImg.Value = ChipsImage;
				cardsImg.Value = CardImage;
				podOffImg.Value = PodImage;
				podOnImg.Value = PodActiveImage;
				timerImg.Value = TimerImage;
				seatImg.Value = SeatImage;

				for (int c = 0; c < SeatPositions.Length; c++)
				{
					XmlElement seat = config.CreateElement("Seat");
					XmlAttribute index = config.CreateAttribute("index");
					XmlAttribute seatX = config.CreateAttribute("x");
					XmlAttribute seatY = config.CreateAttribute("y");
					XmlAttribute stackX = config.CreateAttribute("stackX");
					XmlAttribute stackY = config.CreateAttribute("stackY");
					XmlAttribute buttonX = config.CreateAttribute("buttonX");
					XmlAttribute buttonY = config.CreateAttribute("buttonY");
					tableView.AppendChild(seat);
					seat.Attributes.Append(index);
					seat.Attributes.Append(seatX);
					seat.Attributes.Append(seatY);
					seat.Attributes.Append(stackX);
					seat.Attributes.Append(stackY);
					seat.Attributes.Append(buttonX);
					seat.Attributes.Append(buttonY);

					index.Value = c.ToString();
					seatX.Value = SeatPositions[c].X.ToString();
					seatY.Value = SeatPositions[c].Y.ToString();
					stackX.Value = StackPositions[c].X.ToString();
					stackY.Value = StackPositions[c].Y.ToString();
					buttonX.Value = ButtonPositions[c].X.ToString();
					buttonY.Value = ButtonPositions[c].Y.ToString();
				}
				for (int c = 0; c < CardPositions.Length; c++)
				{
					XmlElement card = config.CreateElement("Card");
					XmlAttribute index = config.CreateAttribute("index");
					XmlAttribute cardX = config.CreateAttribute("x");
					XmlAttribute cardY = config.CreateAttribute("y");
					tableView.AppendChild(card);
					card.Attributes.Append(index);
					card.Attributes.Append(cardX);
					card.Attributes.Append(cardY);

					index.Value = c.ToString();
					cardX.Value = CardPositions[c].X.ToString();
					cardY.Value = CardPositions[c].Y.ToString();
				}

				config.Save(filename);
			}
		}

		private CardImage m_CardImage;
		private ChipsImage m_ChipsImage;
		private SeatImage m_SeatImage;

		private Image m_Background;
		private Image m_Table;
		private Image m_Button;
		private Image m_EmptySeat;
		private Dictionary<string, Image> m_Players = new Dictionary<string, Image>();
		private HashSet<string> m_Requested = new HashSet<string>();

		private TableConfiguration m_Configuration;

		public PokerClientForm Form;
		public WindowsPokerClient Client;
		public PokerTableView View;
		public DateTime SeatStartTime;
		public DateTime SeatEndTime;

		public Card[] MyFoldedCards;
		public bool ShowFoldedCards;
		public int LastButton = -1;

		public int Me
		{
			get
			{
				if (View == null)
					return -1;
				if (string.IsNullOrEmpty(Client.Login))
					return -1;
				for (int c = 0; c < View.Seats.Length; c++)
					if (View.Seats[c] != null && View.Seats[c].Name == Client.Login)
						return c;
				return -1;
			}
		}

		public PokerTableControl()
		{

			ClickSeat += new ClickSeatEventHandler(OnClickSeat);
			ClickMySeat+=new ClickSeatEventHandler(OnClickMySeat);
			ClickCard += new ClickCardEventHandler(OnClickCard);

			#region Configuration
			m_Configuration = new TableConfiguration();
			if (File.Exists("view.xml"))
				m_Configuration.LoadConfiguration("view.xml");
			else
			{
				m_Configuration.TableImage = "Table.png";
				m_Configuration.BackgroundImage= "Table.jpg";
				m_Configuration.ButtonImage = "button.png";
				m_Configuration.CardImage = "cards.png";
				m_Configuration.ChipsImage = "Chips4.png";
				m_Configuration.SeatImage = "EmptySeat.png";
				m_Configuration.PodImage = "BasePod_Off.png";
				m_Configuration.PodActiveImage = "BasePod_On.png";
				m_Configuration.TimerImage = "Timer.png";
				m_Configuration.FontFamily = "Verdana";
				m_Configuration.FontSize = 9;
				m_Configuration.FontColor = Color.White;
				m_Configuration.SelectedColor = Color.Black;
				m_Configuration.Size = new System.Drawing.Size(794, 547);
				m_Configuration.PotPosition = new Point(400, 210);
				m_Configuration.SeatPositions = new Point[]
				{
					new Point(279, 117),
					new Point(519, 117),
					new Point(692, 186),
					new Point(721, 332),
					new Point(583, 439),
					new Point(401, 459),
					new Point(216, 439),
					new Point(74, 332),
					new Point(107, 186)
				};

				m_Configuration.CardPositions = new Point[]
				{
					new Point(270, 280),
					new Point(330, 280),
					new Point(390, 280),
					new Point(470, 280),
					new Point(530, 280)
				};

				m_Configuration.ButtonPositions = new Point[]
				{
					new Point(294, 157),
					new Point(504, 157),
					new Point(607, 196),
					new Point(606, 312),
					new Point(508, 349),
					new Point(406, 359),
					new Point(261, 349),
					new Point(189, 312),
					new Point(192, 196)
				};

				m_Configuration.StackPositions = new Point[]
				{
					new Point(299, 177),
					new Point(499, 177),
					new Point(592, 206),
					new Point(621, 312),
					new Point(533, 339),
					new Point(401, 359),
					new Point(266, 329),
					new Point(174, 312),
					new Point(207, 206)
				};

				if (!(DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime))
					m_Configuration.SaveConfiguration("view.xml");
			}
			#endregion

			LoadConfiguration();

			SetStyle(ControlStyles.ResizeRedraw, true);
			DoubleBuffered = true;
			InitializeComponent();
		}

		protected void LoadConfiguration()
		{
			string[] username = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\');
			string user = username.Length == 2 ? string.Join(".", username[1], username[0]) : username[0];
			string folder = @"C:\Users\" + user + @"\Dropbox\PokerClient\";
			if (!Directory.Exists(folder))
				folder = @"C:\Users\" + username[1] + @"\Dropbox\PokerClient\";
			if (!Directory.Exists(folder))
				folder = string.Empty;
			m_Background = Image.FromFile(folder + m_Configuration.BackgroundImage);
			m_Table = Image.FromFile(folder + m_Configuration.TableImage);
			m_Button = Image.FromFile(folder + m_Configuration.ButtonImage);
			m_CardImage = new CardImage(folder + m_Configuration.CardImage);
			m_ChipsImage = new ChipsImage(folder + m_Configuration.ChipsImage, 4, 5, 3, 1, 5, 25, 100, 500, 2500, 10000, 50000, 100000, 500000, 2500000, 10000000, 50000000, 100000000, 500000000);
			m_EmptySeat = Image.FromFile(folder + m_Configuration.SeatImage);
			m_SeatImage = new SeatImage(folder + m_Configuration.PodActiveImage, folder + m_Configuration.PodImage, folder + m_Configuration.TimerImage, new Point(11, 37));
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);

			try
			{
				Graphics g = e.Graphics;
				bool fourColor = Client.LobbyForm.FourColorDeck;

				double widthRatio = (double)Width / m_Background.Width;
				double heightRatio = (double)Height / m_Background.Height;
				double configWRatio = (double)Width / m_Configuration.Size.Width;
				double configHRatio = (double)Height / m_Configuration.Size.Height;
				g.Clear(BackColor);
				g.DrawImage(m_Background, new Rectangle(0, 0, (int)Width, (int)Height), new Rectangle(0, 0, m_Background.Width, m_Background.Height), GraphicsUnit.Pixel);
				g.DrawImage(m_Table, new Rectangle((int)(100 * widthRatio), (int)(-60 * heightRatio), (int)(m_Table.Width * widthRatio), (int)(m_Table.Height * heightRatio)), new Rectangle(0, 0, m_Table.Width, m_Table.Height), GraphicsUnit.Pixel);

				Font font = new Font(m_Configuration.FontFamily, (float)(m_Configuration.FontSize * configHRatio), FontStyle.Regular);
				Font fontBold = new Font(m_Configuration.FontFamily, (float)(m_Configuration.FontSize * configHRatio), FontStyle.Bold);
				Brush whiteBrush = new SolidBrush(m_Configuration.FontColor);
				Brush blackBrush = new SolidBrush(m_Configuration.SelectedColor);

				if (View != null)
				{
					int me = Me;
					PokerCurrency currency = PokerCurrency.GetCurrency(View.Currency);
					Point buttonPos = m_Configuration.ButtonPositions[View.Button];
					g.DrawImage(m_Button, new Rectangle((int)((buttonPos.X - m_Button.Width / 2.0) * configWRatio), (int)(buttonPos.Y * configHRatio), (int)(m_Button.Width * configWRatio), (int)(m_Button.Height * configHRatio)), new Rectangle(0, 0, m_Button.Width, m_Button.Height), GraphicsUnit.Pixel);

					Image playerImage = null;
					for (int c = 0; c < View.Seats.Length; c++)
					{
						PokerTableView.PokerTableSeatView seat = View.Seats[c];
						Point p = m_Configuration.SeatPositions[c];
						if (seat == null)
						{
							if (View.IsCashGame)
								g.DrawImage(m_EmptySeat, new Rectangle((int)((p.X - 35) * configWRatio), (int)((p.Y - 29) * configHRatio), (int)(widthRatio * 70), (int)(heightRatio * 58)), new Rectangle(0, 0, m_EmptySeat.Width, m_EmptySeat.Height), GraphicsUnit.Pixel);
						}
						else
						{
							if (!m_Players.TryGetValue(seat.Name, out playerImage))
							{
								if (File.Exists("table." + seat.Name + ".png"))
								{
									playerImage = Image.FromFile("table." + seat.Name + ".png");
									m_Players.Add(seat.Name, playerImage);
								}
								else if (!m_Requested.Contains(seat.Name))
								{
									m_Requested.Add(seat.Name);
									Client.RequestTableImage(seat.Name);
								}
							}
							if (seat.Cards != null)
							{
								if (seat.Cards[0] == null)
									g.DrawImage(m_CardImage.GetBack(0), new Rectangle((int)((p.X - 42) * configWRatio), (int)((p.Y - 50) * configHRatio), (int)(widthRatio * 42), (int)(heightRatio * 59)), new Rectangle(0, 0, m_CardImage.Width, m_CardImage.Height), GraphicsUnit.Pixel);
								else
									g.DrawImage(m_CardImage.GetCard(seat.Cards[0], fourColor), new Rectangle((int)((p.X - 56) * configWRatio), (int)((p.Y - 65) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78)), new Rectangle(0, 0, m_CardImage.Width, m_CardImage.Height), GraphicsUnit.Pixel);
								if (seat.Cards[1] == null)
									g.DrawImage(m_CardImage.GetBack(0), new Rectangle((int)(p.X * configWRatio), (int)((p.Y - 50) * configHRatio), (int)(widthRatio * 42), (int)(heightRatio * 59)), new Rectangle(0, 0, m_CardImage.Width, m_CardImage.Height), GraphicsUnit.Pixel);
								else
									g.DrawImage(m_CardImage.GetCard(seat.Cards[1], fourColor), new Rectangle((int)(p.X * configWRatio), (int)((p.Y - 65) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78)), new Rectangle(0, 0, m_CardImage.Width, m_CardImage.Height), GraphicsUnit.Pixel);
							}
							else if (ShowFoldedCards && seat.Index == me && MyFoldedCards != null)
							{
								ColorMatrix fade = new ColorMatrix();
								ImageAttributes attributes = new ImageAttributes();
								fade.Matrix33 = 0.4f;
								attributes.SetColorMatrix(fade, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
								if (MyFoldedCards[0] != null)
									g.DrawImage(m_CardImage.GetCard(MyFoldedCards[0], fourColor), new Rectangle((int)((p.X - 56) * configWRatio), (int)((p.Y - 65) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78)), 0, 0, m_CardImage.Width, m_CardImage.Height, GraphicsUnit.Pixel, attributes);
								if (MyFoldedCards[1] != null)
									g.DrawImage(m_CardImage.GetCard(MyFoldedCards[1], fourColor), new Rectangle((int)(p.X * configWRatio), (int)((p.Y - 65) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78)), 0, 0, m_CardImage.Width, m_CardImage.Height, GraphicsUnit.Pixel, attributes);
							}
							Image seatImage = m_SeatImage.InactiveSeat;
							if (View.CurrentAction == c)
							{
								if (SeatEndTime.CompareTo(DateTime.Now) > 0)
								{
									TimeSpan totalTime = SeatEndTime.Subtract(SeatStartTime);
									TimeSpan currentTime = SeatEndTime.Subtract(DateTime.Now);
									double pct = Math.Min(1.0, Math.Max(0.0, currentTime.TotalMilliseconds / totalTime.TotalMilliseconds));
									seatImage = m_SeatImage.TimerSeat(pct);
								} else
									seatImage = m_SeatImage.ActiveSeat;
							}
							g.DrawImage(seatImage, new Rectangle((int)((p.X - seatImage.Width / 2) * configWRatio), (int)((p.Y - seatImage.Height / 2) * configHRatio), (int)(seatImage.Width * configWRatio), (int)(seatImage.Height * configHRatio)), new Rectangle(0, 0, seatImage.Width, seatImage.Height), GraphicsUnit.Pixel);
							if (playerImage != null)
								g.DrawImage(playerImage, new Rectangle((int)((p.X + 20) * configWRatio), (int)((p.Y - 21) * configHRatio), (int)(31 * configWRatio), (int)(31 * configHRatio)), new Rectangle(0, 0, playerImage.Width, playerImage.Height), GraphicsUnit.Pixel);
						}
					}

					for (int c = 0; c < View.Cards.Length; c++)
						g.DrawImage(m_CardImage.GetCard(View.Cards[c], fourColor), new Rectangle((int)((m_Configuration.CardPositions[c].X - 28) * configWRatio), (int)((m_Configuration.CardPositions[c].Y - 39) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78)), new Rectangle(0, 0, m_CardImage.Width, m_CardImage.Height), GraphicsUnit.Pixel);

					ulong total = 0;
					List<int> indexes;

					for (int s = 0; s < View.Seats.Length; s++)
					{
						PokerTableView.PokerTableSeatView seat = View.Seats[s];
						if (seat == null || seat.Bet == 0)
							continue;
						Point p = m_Configuration.StackPositions[s];
						indexes = m_ChipsImage.GetIndexes((ulong)seat.Bet * (ulong)currency.ChipsMultiplier);
						total += seat.Bet;
						for (int c = 0; c < indexes.Count; c++)
							g.DrawImage(m_ChipsImage.GetImage(indexes[c]), new Rectangle((int)((p.X - m_ChipsImage.Width / 2.0) * configWRatio), (int)((p.Y - c * m_ChipsImage.Depth) * configHRatio), (int)(m_ChipsImage.Width * configWRatio), (int)(m_ChipsImage.Height * configHRatio)), new Rectangle(0, 0, m_ChipsImage.Width, m_ChipsImage.Height), GraphicsUnit.Pixel);
						string text = currency.ToString(seat.Bet);
						SizeF txtSize = g.MeasureString(text, font);
						g.DrawString(text, font, whiteBrush, (int)(p.X * configWRatio - txtSize.Width / 2), (int)((p.Y + 20) * configHRatio));
					}

					ulong amount = (ulong)View.Pot;
					if(View.State != PokerStreetType.Showdown)
						amount -= total;
					if (amount > 0)
					{
						indexes = m_ChipsImage.GetIndexes(amount * (ulong)currency.ChipsMultiplier);
						for (int c = 0; c < indexes.Count; c++)
							g.DrawImage(m_ChipsImage.GetImage(indexes[c]), new Rectangle((int)((m_Configuration.PotPosition.X - m_ChipsImage.Width / 2.0) * configWRatio), (int)((m_Configuration.PotPosition.Y - c * m_ChipsImage.Depth) * configHRatio), (int)(m_ChipsImage.Width * configWRatio), (int)(m_ChipsImage.Height * configHRatio)), new Rectangle(0, 0, m_ChipsImage.Width, m_ChipsImage.Height), GraphicsUnit.Pixel);
						string text = currency.ToString(amount);
						SizeF txtSize = g.MeasureString(text, font);
						g.DrawString(text, font, whiteBrush, (int)(m_Configuration.PotPosition.X * configWRatio - txtSize.Width / 2), (int)((m_Configuration.PotPosition.Y + 20) * configHRatio));
						
					}

					for (int c = 0; c < View.Seats.Length; c++)
					{
						PokerTableView.PokerTableSeatView seat = View.Seats[c];
						if (seat == null)
							continue;
						Point p = m_Configuration.SeatPositions[c];
						string name = seat.Name;
						string info = currency.ToString(seat.Stack);
						if(seat.State != Dll.Cards.Poker.Enums.PokerSeatState.Playing)
							info = "(" + seat.State + ")";
						m_Players.TryGetValue(seat.Name, out playerImage);
						Brush usedBrush = whiteBrush;
						Brush backBrush = blackBrush;
						if (View.CurrentAction == c)
						{
							usedBrush = blackBrush;
							backBrush = whiteBrush;
						}
						Color usedColor = ((SolidBrush)usedBrush).Color;
						Color backColor = ((SolidBrush)backBrush).Color;
						bool chatBox = false;
						string chat = null;
						if (m_Chat.TryGetValue(seat.Name, out chat) && !string.IsNullOrWhiteSpace(chat))
							chatBox = true;
						SizeF txtSize = g.MeasureString(name, font);
						SizeF infoSize = g.MeasureString(info, fontBold);
						if (playerImage != null)
						{
							g.DrawString(name, font, usedBrush, (int)((p.X - 20) * configWRatio - txtSize.Width / 2), (int)((p.Y - 20) * configHRatio));
							g.DrawString(info, fontBold, usedBrush, (int)((p.X - 20) * configWRatio - infoSize.Width / 2), (int)((p.Y - 8) * configHRatio));
						}
						else
						{
							g.DrawString(name, font, usedBrush, (int)((p.X) * configWRatio - txtSize.Width / 2), (int)((p.Y - 20) * configHRatio));
							g.DrawString(info, fontBold, usedBrush, (int)((p.X) * configWRatio - infoSize.Width / 2), (int)((p.Y - 8) * configHRatio));
						}
						if (chatBox)
						{
							TextRenderer.DrawText(g, chat, font, new Rectangle((int)((p.X - 70) * configWRatio), (int)((p.Y - 76) * configHRatio), (int)(140 * configWRatio), (int)(60 * configHRatio)), usedColor, backColor, TextFormatFlags.EndEllipsis | TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter | TextFormatFlags.WordBreak | TextFormatFlags.WordEllipsis);
						}
					}


					if (!string.IsNullOrWhiteSpace(m_SystemMessage) && DateTime.Now.CompareTo(m_SystemMessageTime) <= 0)
					{
						string text = m_SystemMessage;
						SizeF txtSize = g.MeasureString(text, font);

						g.FillRectangle(blackBrush, (int)(Width / 2 - txtSize.Width / 2), (int)(5 * configHRatio), (int)txtSize.Width, (int)txtSize.Height);
						g.DrawRectangle(new Pen(whiteBrush), (int)(Width / 2 - txtSize.Width / 2), (int)(5 * configHRatio), (int)txtSize.Width, (int)txtSize.Height);
						g.DrawString(text, font, whiteBrush, (int)(Width / 2 - txtSize.Width / 2), (int)(5 * configHRatio));

					}
					/*
					if (me != -1 && View.Seats[me].Cards != null && View.Seats[me].Cards[0] != null && View.Seats[me].Cards[1] != null)
					{
						CardSet meSet = new CardSet(View.Seats[me].Cards);
						CardSet boardSet = new CardSet(View.Cards);

						PokerHighHand hand = PokerHighHand.GetBestHand(meSet, boardSet);
						string text = hand.Description;

						Point p = m_Configuration.SeatPositions[me];
						SizeF txtSize = g.MeasureString(text, font);
						Brush usedBrush = whiteBrush;
						Brush backBrush = blackBrush;
						if (View.CurrentAction == me)
						{
							usedBrush = blackBrush;
							backBrush = whiteBrush;
						}

						g.FillRectangle(backBrush, (int)((p.X) * configWRatio - txtSize.Width / 2), (int)((p.Y - 65) * configHRatio - txtSize.Height), (int)txtSize.Width, (int)txtSize.Height);
						g.DrawRectangle(new Pen(usedBrush), (int)((p.X) * configWRatio - txtSize.Width / 2), (int)((p.Y - 65) * configHRatio - txtSize.Height), (int)txtSize.Width, (int)txtSize.Height);
						g.DrawString(text, font, usedBrush, (int)((p.X) * configWRatio - txtSize.Width / 2), (int)((p.Y - 65) * configHRatio - txtSize.Height));

					}
					*/
				}

			}
			catch
			{

			}
		}

		private void DrawText(Graphics g, string text, Font font, Brush back, Brush fore, Rectangle rect)
		{
			throw new NotImplementedException();
			SizeF size = g.MeasureString(text, font);
			if (size.Width > rect.Width)
			{
				int minLines = (int)Math.Ceiling(size.Width / rect.Width);
				string[] words = text.Split(' ');
				if (words.Length < minLines)
				{

				}
			}
		}

		protected override void OnClick(EventArgs e)
		{
			base.OnClick(e);

			double widthRatio = (double)Width / m_Background.Width;
			double heightRatio = (double)Height / m_Background.Height;
			double configWRatio = (double)Width / m_Configuration.Size.Width;
			double configHRatio = (double)Height / m_Configuration.Size.Height;

			Point point = PointToClient(Cursor.Position);
			int me = Me;

			for (int c = 0; c < m_Configuration.SeatPositions.Length; c++)
			{
				Point seat = m_Configuration.SeatPositions[c];
				int dx = Math.Abs(point.X - (int)(seat.X * configWRatio));
				int dy = Math.Abs(point.Y - (int)(seat.Y * configHRatio));

				if (View.Seats[c] == null && View.IsCashGame && dx < 35 && dy < 29)
				{
					ClickSeatEventArgs arg = new ClickSeatEventArgs();
					arg.Index = c;
					if(ClickSeat != null)
						ClickSeat.Invoke(arg);
				}

				if (dx < m_SeatImage.InactiveSeat.Width / 2 && dy < m_SeatImage.InactiveSeat.Height / 2)
				{
					if (me == c)
					{
						ClickSeatEventArgs arg = new ClickSeatEventArgs();
						arg.Index = c;
						if(ClickMySeat != null)
							ClickMySeat.Invoke(arg);
						ShowFoldedCards = !ShowFoldedCards;
						if(MyFoldedCards != null)
							Refresh();
					}
				}
			}

			if (me != -1)
			{
				PokerTableView.PokerTableSeatView seat = View.Seats[me];
				Point p = m_Configuration.SeatPositions[me];
				if (seat.Cards != null)
				{
					Card card = null;
					if (seat.Cards[0] != null)
					{
						Rectangle r = new Rectangle((int)((p.X - 56) * configWRatio), (int)((p.Y - 65) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78));
						if (r.Contains(point))
							card = seat.Cards[0];
					}
					if (seat.Cards[1] != null)
					{
						Rectangle r = new Rectangle((int)(p.X * configWRatio), (int)((p.Y - 65) * configHRatio), (int)(widthRatio * 56), (int)(heightRatio * 78));
						if (r.Contains(point))
							card = seat.Cards[1];
					}
					if (card != null && ClickCard != null)
					{
						ClickCardEventArgs arg = new ClickCardEventArgs();
						arg.Index = me;
						arg.Card = card;
						ClickCard.Invoke(arg);
					}
				}
			}
		}

		public class ClickSeatEventArgs : EventArgs
		{
			public int Index;
		}
		public class ClickCardEventArgs : ClickSeatEventArgs
		{
			public Card Card;
		}

		public delegate void ClickSeatEventHandler(ClickSeatEventArgs e);
		public delegate void ClickCardEventHandler(ClickCardEventArgs e);

		public event ClickSeatEventHandler ClickSeat;
		public event ClickSeatEventHandler ClickMySeat;
		public event ClickCardEventHandler ClickCard;

		protected virtual void OnClickMySeat(ClickSeatEventArgs e)
		{

		}

		protected virtual void OnClickSeat(ClickSeatEventArgs e)
		{

		}

		protected virtual void OnClickCard(ClickCardEventArgs e)
		{

		}

		private Dictionary<string, string> m_Chat = new Dictionary<string, string>();
		private Dictionary<string, Thread> m_ChatRefreshThread = new Dictionary<string, Thread>();
		public void Say(string playerName, string message)
		{
			if (View != null && View.IsSitted(playerName))
			{
				lock (m_Chat)
				{
					if (m_ChatRefreshThread.ContainsKey(playerName))
					{
						m_ChatRefreshThread[playerName].Abort();
						m_ChatRefreshThread.Remove(playerName);
						m_Chat.Remove(playerName);
					}
					m_Chat.Add(playerName, message);
					Refresh();
					Thread removeThread = new Thread(delegate()
					{
						try
						{
							Thread.Sleep(10000);
							lock (m_Chat)
							{
								m_Chat.Remove(playerName);
								Refresh();
							}
						}
						catch(Exception e)
						{
						
						}
					});
					m_ChatRefreshThread.Add(playerName, removeThread);
					removeThread.Start();
				}
			}
		}

		private string m_SystemMessage;
		private DateTime m_SystemMessageTime;

		public void BlindGoesUp(ulong smallBlind, ulong bigBlind, ulong ante)
		{
			m_SystemMessageTime = DateTime.Now.AddSeconds(8);
			PokerCurrency currency = PokerCurrency.GetCurrency(View.Currency);
			if (ante == 0)
				m_SystemMessage = string.Format("Blinds are going up, blinds {0}/{1}.", currency.ToString(smallBlind), currency.ToString(bigBlind));
			else
				m_SystemMessage = string.Format("Blinds are going up, blinds {0}/{1} ante {2}.", currency.ToString(smallBlind), currency.ToString(bigBlind), currency.ToString(ante));

		}
	}
}

